package com.trnnn.strutslit;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import com.trnnn.strutslit.annotation.Action;
import com.trnnn.strutslit.annotation.Namespace;

public final class ActionTable {

	private ActionTable() {
	}

	public static final ActionTable INSTANCE = new ActionTable();

	public static ActionTable getIntance() {
		return INSTANCE;
	}

	private static final Map<ActionKey, ActionModel> actionTable = new TreeMap<ActionKey, ActionModel>();
	
	private static Set<ActionKey> actionKeySet;

	class ActionModel {
		protected ActionModel() {
		}

		public Class<?> clazz;
		public Action action;
		public Method actionMethod;
		public int order;
	}
	
	public static void initActionKeySet(){
		actionKeySet=actionTable.keySet();
	}
	
	public static Set<ActionKey> getActionKeySet(){
		return actionKeySet;
	}
	
	public static Set<ActionKey> getActionKeySet(String namespace){
		Set<ActionKey> keys=new TreeSet<ActionKey>();
		for(ActionKey sourceKey:actionKeySet){
			if(sourceKey.namespace().equals(namespace)){
				keys.add(sourceKey);
			}
		}
		return keys;
	}

	public static ActionModel createActionModel(Action action, Class<?> clazz,
			Method method) {
		ActionModel actionModel = INSTANCE.new ActionModel();
		actionModel.action = action;
		actionModel.clazz = clazz;
		actionModel.actionMethod = method;
		return actionModel;
	}
	
	public static ActionModel getActionModel(ActionKey key){
		return actionTable.get(key);
	}

	public static void registerActionModel(Action action, Class<?> clazz,
			Method method) {
		ActionModel actionModel = createActionModel(action, clazz, method);
		registerActionModel(actionModel);
	}

	public static void registerActionModel(ActionModel actionModel) {
		String actionName = actionModel.action.name();
		String namespace;// = actionModel.namespace;
		if(actionModel.clazz.isAnnotationPresent(Namespace.class)){
			namespace=actionModel.clazz.getAnnotation(Namespace.class).name();
		}
		else{
			namespace=GlobalContext.DEFAULT_NAMESPACE;
		}
		String pattern = actionModel.action.pattern();
		int order=actionModel.action.order();
		ActionKey key = new ActionKey(namespace,actionName,pattern,order);
		actionTable.put(key, actionModel);
	}

	public static void unregisterActionModel(ActionKey key) {
		actionTable.remove(key);
	}
}
